/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tracetoautomata;

import alloytoy.Util;
import edu.mit.csail.sdg.alloy4compiler.ast.Attr;
import edu.mit.csail.sdg.alloy4compiler.ast.Sig;
import java.lang.String;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * 
 * @author daniel
 */
public class State implements Comparable{
    /**
     * Dois estados  de assinaturas s,s' são iguais se:
     *  - s e s' têm as mesmas relações.
     *  - para cada relação r, os objectios que se relacionam com s por r, relacionam-se com s' por r.
     *  Todos os estados das assinaturas que aparecem nas relações, são iguais.
     */

    public int number=0;
    private Map<String, ArrayList<String>> relState;
    private String atom;
    private boolean orderingSig;

    public State(String atomName, boolean ordSig){
        atom=atomName;
        orderingSig=ordSig;
        relState = new HashMap<String, ArrayList<String>>();
    }

    public void setNumber(int n){ number=n; }

    public String getAtom() { return atom; }

    public boolean isOrderingState() { return orderingSig; }


    /*public void newRel(String relName, ArrayList<State> states){
        relState.put(atom, states);
    }
    public void newRel(String relName){
        relState.put(atom, new ArrayList<State>());
    }*/

    public String getDescription()
    {
        String s="";
        SortedSet<String> set = new TreeSet<String>();
        set.addAll(relState.keySet());
        for(String rel : set)
        {
            ArrayList<String> atoms = relState.get(rel);
            s+=rel+"";
            for(String tmp : atoms)
            {

                s+=tmp.substring(0,tmp.indexOf("$"));
            }
        }
        return s;
    }

    public void addStates(String relName, ArrayList<String> atoms)
    {
        atoms.remove(atom);
        if(relState.get(relName)!=null)
        {
            ArrayList<String> atomsR = relState.get(relName);
            atomsR.addAll(atoms);
            relState.put(relName, atomsR);
        }
        else{
            relState.put(relName, atoms);
        }
    }
    

    public void addAtom(String relName, String atom){
        ArrayList<String>  states = relState.get(relName);
        if(states!=null){
            states.add(atom);
        }
        else{
            states = new ArrayList<String>();
            states.add(atom);
        }
        relState.put(relName,states);
    }

    public ArrayList<String> getRel(String relName){
        return relState.get(relName);
    }

    public Map<String, ArrayList<String>> getAllRels(){
        return relState;
    }

    public boolean MyEquals(Object obj){
        //System.out.println("EQUALS");
        if(obj==null){ System.out.println("False1"); return false; }
        if(!(obj instanceof State)){ System.out.println("False2"); return false; }
        final State tmp = (State) obj;

        
        //if(!tmp.getAtom().equals(atom)){ return false; }

        //Todas as relações têm que ser iguais.
        if(!relState.keySet().equals(tmp.getAllRels().keySet())){
            /*System.out.println("False3");
            System.out.println(this.atom);
            System.out.println(relState.keySet());
            System.out.println(tmp.getAtom());
            System.out.println(tmp.getAllRels().keySet());*/
            return false;
        }
        for(String rel1 : relState.keySet()){
            for(String rel2 : tmp.getAllRels().keySet()){
                //Todos os states de cada relação têm que ser iguais
                if(rel1.equals(rel2))
                {
                    if(!relState.get(rel1).equals(tmp.relState.get(rel2)))
                        
                        return false;
                }
            }
        }
        return true;
    }

    public int getNumber(){ return number;}

    
    public int compareTo(Object o) {
        return ((State) o).atom.compareTo(((State) o).atom);
    }

    @Override
    public String toString(){
        return atom;
    }
    
}
